package com.mineoj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mineoj.common.ErrorCode;
import com.mineoj.exception.BusinessException;
import com.mineoj.model.dto.solutioncomment.SolutionCommentAddRequest;
import com.mineoj.model.dto.solutioncomment.SolutionCommentQueryRequest;
import com.mineoj.model.entity.Question;
import com.mineoj.model.entity.Solution;
import com.mineoj.model.entity.SolutionComment;
import com.mineoj.model.entity.User;
import com.mineoj.model.vo.SolutionCommentVO;
import com.mineoj.service.SolutionCommentService;
import com.mineoj.mapper.SolutionCommentMapper;
import com.mineoj.service.SolutionService;
import com.mineoj.service.UserService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author 明月
* @description 针对表【solution_comment(题解评论)】的数据库操作Service实现
* @createDate 2025-04-05 16:15:45
*/
@Service
public class SolutionCommentServiceImpl extends ServiceImpl<SolutionCommentMapper, SolutionComment>
    implements SolutionCommentService{

    @Resource
    private SolutionService solutionService;

    @Resource
    private SolutionCommentMapper solutionCommentMapper;

    @Resource
    private UserService userService;

    /**
     * 添加评论
     * @param solutionCommentAddRequest 评论信息
     * @param loginUser 登录用户
     * @return 评论id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public long doSolutionComment(SolutionCommentAddRequest solutionCommentAddRequest, User loginUser) {
        // 校验内容是否为空
        if (solutionCommentAddRequest.getContent() == null || solutionCommentAddRequest.getContent().isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容不能为空");
        }

        long solutionId = solutionCommentAddRequest.getSolutionId();
        // 判断实体是否存在
        Solution solution = solutionService.getById(solutionId);
        if (solution == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }

        // 构建评论对象
        SolutionComment solutionComment = new SolutionComment();
        solutionComment.setSolutionId(solutionId);
        solutionComment.setContent(solutionCommentAddRequest.getContent());
        solutionComment.setUserId(loginUser.getId());

        boolean save = this.save(solutionComment);
        if (!save) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据插入失败");
        }

        // 更新题解评论数
        boolean updateSuccess = solutionService.update()
                .eq("id", solutionId)
                .setSql("commentNum = commentNum + 1")
                .update();
        if (!updateSuccess) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "评论数更新失败");
        }

        return solutionComment.getId();
    }

    /**
     * 删除评论
     * @param id 评论ID
     * @param loginUser 登录用户
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteSolutionComment(long id, User loginUser) {
        // 判断是否存在
        SolutionComment oldSolutionComment = this.getById(id);
        if (oldSolutionComment == null ) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 仅本人或管理员可删除
        if (!oldSolutionComment.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        if (this.removeById(id)) {
            // 更新题解评论数
            boolean updateSuccess = solutionService.update()
                    .eq("id", oldSolutionComment.getSolutionId())
                    .setSql("commentNum = commentNum - 1")
                    .update();
            if (!updateSuccess) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "评论数更新失败");
            }
            return true;
        }

        return false;
    }


    /**
     * 获取评论封装
     * @param solutionComment 评论
     * @param loginUser 登录用户
     * @return 评论封装
     */
    @Override
    public SolutionCommentVO getSolutionCommentVO(SolutionComment solutionComment, User loginUser) {
        SolutionCommentVO solutionCommentVO = SolutionCommentVO.objToVo(solutionComment);
        return solutionCommentVO;
    }

    /**
     * 获取评论分页封装，包含用户信息
     * @param solutionCommentPage 分页对象
     * @param request
     * @return 分页对象
     */
    @Override
    public Page<SolutionCommentVO> getSolutionCommentVOPage(Page<SolutionComment> solutionCommentPage, HttpServletRequest request) {
        List<SolutionComment> solutionCommentList = solutionCommentPage.getRecords();
        Page<SolutionCommentVO> solutionCommentVOPage = new Page<>(solutionCommentPage.getCurrent(), solutionCommentPage.getSize(), solutionCommentPage.getTotal());
        if (CollectionUtils.isEmpty(solutionCommentList)) {
            return solutionCommentVOPage;
        }
        // 1. 关联查询用户信息
        Set<Long> userIdSet = solutionCommentList.stream().map(SolutionComment::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 2. 填充信息
        List<SolutionCommentVO> solutionCommentVOList = solutionCommentList.stream().map(solutionComment -> {
            SolutionCommentVO solutionCommentVO = SolutionCommentVO.objToVo(solutionComment);
            Long userId = solutionComment.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            solutionCommentVO.setUserVO(userService.getUserVO(user));
            return solutionCommentVO;
        }).collect(Collectors.toList());
        solutionCommentVOPage.setRecords(solutionCommentVOList);
        return solutionCommentVOPage;
    }


}




